package com.ld.bisystem.modules.bi.dao.service;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.ld.bisystem.modules.bi.dao.JdbcDao;
import com.ld.bisystem.modules.bi.entity.SuperEntity;
import com.ld.bisystem.util.*;
import com.ld.bisystem.wrapper.JoinWrapper;
import com.ld.bisystem.wrapper.anno.JoinDelete;
import com.ld.bisystem.wrapper.anno.JoinField;
import com.ld.bisystem.wrapper.anno.JoinQuery;
import com.ld.bisystem.wrapper.anno.JoinSave;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * e
 * List e
 * Map List e
 * Map e
 */
public class JdbcService {

    List<BaseMapper> mapperList;

    JdbcDao viewDao;

    private void entitySetList(Object val,List list){
        if(val instanceof SuperEntity){
            list.add(val);
        }else if(val instanceof Map){
            Map map = (Map)val;
            for (Object o : map.values()) {
                entitySetList(o,list);
            }
        }else if(val instanceof Collection){
            Collection coll = (Collection)val;
            for (Object o : coll) {
                entitySetList(o,list);
            }
        }
    }

    private BaseMapper getBaseMapper(Class clazz){
       for (BaseMapper mapper : mapperList) {
           Class entityClass =   GenericUtil.getGeneric(mapper.getClass(),BaseMapper.class,0);
           if(entityClass.equals(clazz)){
               return mapper;
           }
       }
       throw new RuntimeException("请检查是否存在对应Dao："+clazz);
    }



    private Class getFieldClass(Field field){
        int[] paths = GenericUtil.getFieldGeneric(field,SuperEntity.class);

        return GenericUtil.getFieldGeneric(field,paths);
    }

    private List getFieldValue(Object obj,Field field){

        Object entity =  ReflectionUtil.invokeGetter(obj,field.getName());
        if(entity instanceof List){
            return (List)entity;
        }else {
            return Arrays.asList(entity);
        }
    }

    public void  save(Object obj){

        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            JoinSave joinEntity =  AnnotationUtils.findAnnotation(field,JoinSave.class);
            if(joinEntity == null){
                continue;
            }

            List<SuperEntity> list =  new LinkedList<>();
            Object val =  ReflectionUtil.invokeGetter(obj,field.getName());
            entitySetList(val,list);

            BaseMapper mapper =  getBaseMapper(getFieldClass(field));

            for (SuperEntity entity : list) {
                //脚本执行
                if(StringUtil.isNotNull(joinEntity.get())){
                    SuperEntity getEntity = ReflectionUtil.invokeGetter(obj, joinEntity.get());
                    ReflectionUtil.invokeSetter(entity,joinEntity.set(),getEntity);
                }

                if(StringUtil.isNull(entity.getId())){
                    mapper.insert(entity);
                }else {
                    mapper.updateById(entity);
                }
            }

        }

    }

    public void delete(Object obj){
        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            JoinDelete joinEntity = AnnotationUtils.findAnnotation(field, JoinDelete.class);
            if (joinEntity == null) {
                continue;
            }
            List<SuperEntity> list =  new LinkedList<>();
            Object val =  ReflectionUtil.invokeGetter(obj,field.getName());
            entitySetList(val,list);

            BaseMapper mapper =  getBaseMapper(getFieldClass(field));

            List<String> ids =  list.stream().map(v -> v.getId()).collect(Collectors.toList());
            if(ids.isEmpty()){
                continue;
            }
            mapper.deleteBatchIds(ids);
        }



    }

    public void query(Object obj){
        for (Field field : ReflectionUtil.getAllDeclaredFields(obj.getClass())) {
            JoinQuery joinQuery = AnnotationUtils.findAnnotation(field, JoinQuery.class);
            if (joinQuery == null) {
                continue;
            }
            Class<SuperEntity> entityClass =  getFieldClass(field);

            SuperEntity entity =  ReflectionUtil.newInstance(entityClass);
            JoinWrapper jw = new JoinWrapper<>(entity);
            for (JoinField joinField : joinQuery.value()) {
                Object val =  ReflectionUtil.invokeGetter(obj,joinField.valueField());
                jw.where(joinField.columnName(),joinField.value(),val,joinField.and());
            }
            List value =  viewDao.query(jw);
            //设置值
            querySave(obj,joinQuery, field,value);

        }
    }

    private void querySave(Object obj,JoinQuery joinQuery, Field field,List value){
        int[] ds = GenericUtil.getFieldGeneric(field,SuperEntity.class);

        Object val = value;
        //e
        //map e
        //map List e
        //list e
        if(ds.length == 1){
            val = value.get(0);
        }else{

            int[] ps = ListUtil.arrCopy(ds,ds.length - 1);

            Class cla=  GenericUtil.getFieldGeneric(field,ps);
            if(Map.class.isAssignableFrom(cla)){
                //情况2
                val = MapUtil.objToMap(value,joinQuery.group()[0]);
            }else if(List.class.isAssignableFrom(cla)){
                if(ps.length == 3){
                    //情况3
                     val = MapUtil.groupList(value,joinQuery.group());

                }else {
                    //情况4

                }
            }
        }
        ReflectionUtil.invokeSetter(obj,field.getName(),val);

    }
}
